package top.huanyv.tools.bean;

import java.util.function.Function;
import java.util.function.Supplier;

/**
 * @author huanyv
 * @date 2023/3/10 12:14
 */
public class Promise<V> {

    private final V v;

    public Promise(V v) {
        this.v = v;
    }

    public <R> Promise<R> then(Function<V, R> callback) {
        R result = callback.apply(v);
        return new Promise<>(result);
    }

    public <R> Promise<R> then(Function<V, R> callback, Function<Exception, R> err) {
        R result = null;
        try {
            result = callback.apply(v);
        } catch (Exception e) {
            result = err.apply(e);
        }
        return new Promise<>(result);
    }

    public <R> Promise<R> then(Function<V, R> callback, Function<Exception, R> err, Runnable runnable) {
        R result = null;
        try {
            result = callback.apply(v);
        } catch (Exception e) {
            result = err.apply(e);
        } finally {
            runnable.run();
        }
        return new Promise<>(result);
    }

    public <R> R then(Supplier<R> callback) {
        return callback.get();
    }

    public <R> R then(Supplier<R> callback, Function<Exception, R> err) {
        R result = null;
        try {
            result = callback.get();
        } catch (Exception e) {
            result = err.apply(e);
        }
        return result;
    }

    public <R> R then(Supplier<R> callback, Function<Exception, R> err, Runnable runnable) {
        R result = null;
        try {
            result = callback.get();
        } catch (Exception e) {
            result = err.apply(e);
        } finally {
            runnable.run();
        }
        return result;
    }

    @Override
    public String toString() {
        return "Promise(" + v + ")";
    }
}
